package com.fengzheng.basic.service.sys.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fengzheng.basic.common.config.authorization.login.AuthUser;
import com.fengzheng.basic.common.config.response.exception.ServiceException;
import com.fengzheng.basic.mapper.sys.SysUserMapper;
import com.fengzheng.basic.model.vo.SysMenuVo;
import com.fengzheng.basic.model.po.SysUserPo;
import com.fengzheng.basic.model.po.SysUserRolePo;
import com.fengzheng.basic.service.sys.ISysMenuService;
import com.fengzheng.basic.service.sys.ISysRoleService;
import com.fengzheng.basic.service.sys.ISysUserRoleService;
import com.fengzheng.basic.service.sys.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper,SysUserPo>
        implements ISysUserService, UserDetailsService {

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @Autowired
    private ISysMenuService sysMenuService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try{
            SysUserPo sysUserPo = this.getOne(Wrappers.lambdaQuery(SysUserPo.class).eq(SysUserPo::getAccount,username));

            if (Objects.isNull(sysUserPo)) {
                throw new ServiceException("用户不存在");
            }

            //查找对应角色
            List<SysUserRolePo> userRolePoList = sysUserRoleService.list(Wrappers.lambdaQuery(SysUserRolePo.class).eq(SysUserRolePo::getUserId,sysUserPo.getId()));
            List<Long> roleIds = userRolePoList.stream().map(SysUserRolePo::getRoleId).collect(Collectors.toList());

            // 查询角色对应菜单权限
            Collection<? extends GrantedAuthority> authorities = null;
            if (CollectionUtil.isNotEmpty(roleIds)) {
                List<SysMenuVo> sysMenuDtos = sysMenuService.findMenuByRoleIds(roleIds);
                List<String> permissions = new ArrayList<>();
                for (SysMenuVo sysMenuDto : sysMenuDtos) {
                    if (StrUtil.isNotEmpty(sysMenuDto.getPermission())) {
                        permissions.add(sysMenuDto.getPermission());
                    }
                }
                authorities = AuthorityUtils.createAuthorityList(permissions.toArray(new String[0]));
            }

            AuthUser authUser = new AuthUser(sysUserPo.getId(), sysUserPo.getAccount(), sysUserPo.getPassword(),-1L,
                    roleIds, null, false, authorities);

            return authUser;
        } catch (ServiceException e){
            throw e;//在外部会被处理成 InternalAuthenticationServiceException
        } catch (UsernameNotFoundException e){
            throw e; ////在外部会被处理成 AuthenticationServiceException
        } catch (Exception e){
            throw new InternalAuthenticationServiceException("系统异常");
        }
    }

}
